package com.example.l2048;

import android.animation.Animator;
import android.content.Context;
import android.graphics.Point;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;

import java.util.Vector;

public class AnimatorController {
    AnimatorController(Context _parentContext, GameCanvas _parentGameCanvas, int _cardWidth, int _dxWidth){
        //设置父级控件
        this.parentContext = _parentContext;
        this.parentGameCanvas = _parentGameCanvas;
        this.cardWidth = _cardWidth;
        this.dxWidth = _dxWidth;
        //创建状态网络
        this.StateGird = new int[4][4];
        this.ClearState();
        //动画栈
        moveAnimationStack = new Vector();
        scaleAnimationStack = new Vector();
    }
    //移动函数
    public void MoveUp(){
        boolean isMove = false;
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                for (int y1 = y+1; y1 < 4; y1++) {
                    if (StateGird[x][y1] > 0) {
                        if (StateGird[x][y] <=0 ) {
                            //添加动画
                            AddMoveAnimation(new Point(x,y1), new Point(x,y), StateGird[x][y1]);
                            StateGird[x][y] = StateGird[x][y1];
                            StateGird[x][y1] = 0;
                            y--;
                            isMove = true;

                        }
                        else if (StateGird[x][y] == StateGird[x][y1]) {
                            //添加动画
                            AddMoveAnimation(new Point(x,y), new Point(x,y), StateGird[x][y]);
                            AddMoveAnimation(new Point(x,y1), new Point(x,y), StateGird[x][y1]);
                            scaleAnimationStack.addElement(new Point(x,y));
                            StateGird[x][y] = StateGird[x][y] * 2;
                            StateGird[x][y1] = 0;
                            isMove = true;

                        }

                        break;
                    }
                }
            }
        }
        if(isMove) {
            PlayMoveAnimation();
            PlayScaleAnimataion();
            AddCard();
        }
    }
    public void MoveDown(){
        boolean isMove = false;
        for (int x = 0; x <4; x++) {
            for (int y = 3; y >=0; y--) {
                for (int y1 = y-1; y1 >=0; y1--) {
                    if (StateGird[x][y1] >0 ) {
                        if (StateGird[x][y] <= 0) {
                            //添加动画
                            AddMoveAnimation(new Point(x,y1), new Point(x,y), StateGird[x][y1]);
                            StateGird[x][y] = StateGird[x][y1];
                            StateGird[x][y1] = 0;
                            y++;
                            isMove = true;

                        }
                        else if (StateGird[x][y] == StateGird[x][y1]) {
                            //添加动画
                            AddMoveAnimation(new Point(x,y1), new Point(x,y), StateGird[x][y1]);
                            AddMoveAnimation(new Point(x,y), new Point(x,y), StateGird[x][y]);
                            scaleAnimationStack.addElement(new Point(x,y));
                            StateGird[x][y] = StateGird[x][y] * 2;
                            StateGird[x][y1] = 0;
                            isMove = true;

                        }
                        break;
                    }
                }
            }
        }


        if(isMove) {
            PlayMoveAnimation();
            PlayScaleAnimataion();
            AddCard();
        }
    }
    public void MoveLeft(){
        boolean isMove = false;
        for (int y = 0; y < 4; y++) {
            for (int x = 0; x < 4; x++) {
                for (int x1 = x+1; x1 < 4; x1++) {
                    if (StateGird[x1][y] > 0) {
                        if (StateGird[x][y] <= 0) {
                            //添加动画
                            AddMoveAnimation(new Point(x1,y), new Point(x,y), StateGird[x1][y]);
                            StateGird[x][y] = StateGird[x1][y];
                            StateGird[x1][y] = 0;
                            x--;
                            isMove = true;

                        }
                        else if (StateGird[x][y] == StateGird[x1][y]) {
                            //添加动画
                            AddMoveAnimation(new Point(x,y), new Point(x,y), StateGird[x][y]);
                            AddMoveAnimation(new Point(x1,y), new Point(x,y), StateGird[x1][y]);
                            scaleAnimationStack.addElement(new Point(x,y));
                            StateGird[x][y] = StateGird[x][y] * 2;
                            StateGird[x1][y] = 0;
                            isMove = true;

                        }
                        break;
                    }
                }
            }
        }

        if(isMove) {
            PlayMoveAnimation();
            PlayScaleAnimataion();
            AddCard();
        }
    }
    public void MoveRight(){
        boolean isMove = false;
        for (int y = 0; y < 4; y++) {
            for (int x = 3; x >=0; x--) {
                for (int x1 = x-1; x1 >=0; x1--) {
                    if (StateGird[x1][y] > 0) {
                        if (StateGird[x][y] <= 0) {
                            //添加动画
                            AddMoveAnimation(new Point(x1,y), new Point(x,y), StateGird[x1][y]);
                            StateGird[x][y] = StateGird[x1][y];
                            StateGird[x1][y] = 0;
                            x++;
                            isMove = true;

                        }
                        else if (StateGird[x][y] == StateGird[x1][y]) {
                            //添加动画
                            AddMoveAnimation(new Point(x,y), new Point(x,y), StateGird[x][y]);
                            AddMoveAnimation(new Point(x1,y), new Point(x,y), StateGird[x1][y]);
                            scaleAnimationStack.addElement(new Point(x,y));
                            StateGird[x][y] = StateGird[x][y] * 2;
                            StateGird[x1][y] = 0;
                            isMove = true;
                        }
                        break;
                    }
                }
            }
        }

        if(isMove) {
            PlayMoveAnimation();
            PlayScaleAnimataion();
            AddCard();
        }
    }
    //动画相关
    public void ClearState() {
        for(int x = 0; x < 4; ++x){
            for(int y = 0; y < 4; ++y){
                this.StateGird[x][y] = 0;
            }
        }
        parentGameCanvas.UpdateState(this.StateGird);
    }
    public void AddCard(){
        //获取合法的添加位置
        Vector legalPosition = new Vector();
        for( int y = 0; y < 4; ++y ){
            for( int x = 0; x < 4; ++x){
                if( StateGird[x][y] == 0 ){
                    legalPosition.add(new Point(x,y));
                }
            }
        }
        if(legalPosition.size() <= 0) return;
        //随机产生添加位置
        final Point addPosition = new Point((Point)legalPosition.elementAt((int)(Math.random()*legalPosition.size())));

        //计算坐标
        int startX = addPosition.x*(cardWidth) + (addPosition.x+1)*dxWidth;
        int startY = addPosition.y*(cardWidth) + (addPosition.y+1)*dxWidth;

        //产生随机数
        final int rand = (Math.random() > 0.1 ? 2 : 4);

        final Card cardAnimation = new Card(parentContext, cardWidth, startX, startY);
        cardAnimation.SetCardNumber(rand);
        ScaleAnimation scaleAnimation = new ScaleAnimation(0f, 1f, 0f, 1f,
                cardWidth/2, cardWidth/2);
        scaleAnimation.setStartOffset(100);
        scaleAnimation.setDuration(100);

        scaleAnimation.setAnimationListener(new Animation.AnimationListener(){
            public void onAnimationStart(Animation animation) {
                // TODO Auto-generated method stub
            }
            public void onAnimationEnd(Animation animation) {
                // TODO Auto-generated method stub
                //添加卡片属性
                StateGird[addPosition.x][addPosition.y] = rand;
                parentGameCanvas.removeView(cardAnimation);
                parentGameCanvas.UpdateState(StateGird);
                if( IsGameEnd() == true ) parentGameCanvas.GameEnd();
            }
            public void onAnimationRepeat(Animation animation) {
                // TODO Auto-generated method stub
            }
        });

        cardAnimation.startAnimation(scaleAnimation);
        parentGameCanvas.addView(cardAnimation);
    }
    public void AddMoveAnimation(Point form, Point to, int number){
        for(int i = 0; i < moveAnimationStack.size(); ++i){
            MoveAnimation temp = (MoveAnimation) moveAnimationStack.elementAt(i);
            if(temp.to == form) {
                temp.to = to;
                moveAnimationStack.setElementAt(temp,i);
                return;
            }
        }

        MoveAnimation temp = new MoveAnimation(form, to, number);
        moveAnimationStack.addElement(temp);
    }
    public void PlayMoveAnimation(){

        for(int i = 0; i < moveAnimationStack.size(); ++i){
            MoveAnimation temp = (MoveAnimation) moveAnimationStack.elementAt(i);
            //创建动画卡片
            final Card animationCard = new Card(parentContext, cardWidth,
                    dxWidth*(temp.from.x+1)+cardWidth*temp.from.x,
                    dxWidth*(temp.from.y+1)+cardWidth*temp.from.y);
            animationCard.SetCardNumber(temp.number);
            //创建动画
            TranslateAnimation translateAnimation = new TranslateAnimation(
                    0,
                    dxWidth*(temp.to.x-temp.from.x)+cardWidth*(temp.to.x-temp.from.x),
                    0,
                    dxWidth*(temp.to.y-temp.from.y)+cardWidth*(temp.to.y-temp.from.y)
                    );
            translateAnimation.setDuration(100);
            translateAnimation.setInterpolator(new LinearInterpolator());
            translateAnimation.setAnimationListener(new Animation.AnimationListener(){
                public void onAnimationStart(Animation animation) {
                    // TODO Auto-generated method stub
                }
                public void onAnimationEnd(Animation animation) {
                    // TODO Auto-generated method stub
                    parentGameCanvas.removeView(animationCard);
                    parentGameCanvas.UpdateState(StateGird);
                }
                public void onAnimationRepeat(Animation animation) {
                    // TODO Auto-generated method stub
                }
            });
            animationCard.startAnimation(translateAnimation);
            parentGameCanvas.addView(animationCard);
            parentGameCanvas.ClearCardGrid();
        }
        moveAnimationStack.clear();
    }
    public void PlayScaleAnimataion(){
        for(int i = 0; i < scaleAnimationStack.size(); ++i){
            Point temp = (Point) scaleAnimationStack.elementAt(i);
            int startX = dxWidth*(temp.x+1)+cardWidth*temp.x;
            int startY = dxWidth*(temp.y+1)+cardWidth*temp.y;
            //创建动画卡片
            final Card animationCard2 = new Card(parentContext, cardWidth, startX, startY);
            animationCard2.SetCardNumber(StateGird[temp.x][temp.y]);
            parentGameCanvas.UpdateScore(StateGird[temp.x][temp.y]);
            //创建动画
            ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.20f,
                    1.0f, 1.20f,
                    cardWidth/2, cardWidth/2);
            scaleAnimation.setStartOffset(100);
            scaleAnimation.setDuration(100);
            scaleAnimation.setAnimationListener(new Animation.AnimationListener(){
                public void onAnimationStart(Animation animation) {
                    // TODO Auto-generated method stub
                }
                public void onAnimationEnd(Animation animation) {
                    parentGameCanvas.removeView(animationCard2);
                }
                public void onAnimationRepeat(Animation animation) {
                    // TODO Auto-generated method stub
                }
            });
            animationCard2.startAnimation(scaleAnimation);
            parentGameCanvas.addView(animationCard2);
        }
        scaleAnimationStack.clear();
    }
    //检测游戏是否结束
    public boolean IsGameEnd(){
        for( int y = 0; y < 4; ++y ){
            for( int x = 0; x < 4; ++x){
                //上
                if( y - 1 >= 0 && (StateGird[x][y] == 0 ||
                        StateGird[x][y-1] == StateGird[x][y])){
                    return false;
                }
                //下
                if( y + 1 < 4 && (StateGird[x][y] == 0 ||
                        StateGird[x][y+1] == StateGird[x][y])){
                    return false;
                }
                //左
                if( x - 1 >= 0 && (StateGird[x][y] == 0 ||
                        StateGird[x-1][y] == StateGird[x][y])){
                    return false;
                }
                //右
                if( x + 1 < 4 && (StateGird[x][y] == 0 ||
                        StateGird[x+1][y] == StateGird[x][y])){
                    return false;
                }
            }
        }
        return true;
    }

    //private
    private Context parentContext;
    private GameCanvas parentGameCanvas;
    private int cardWidth;
    private int dxWidth;
    int[][] StateGird;          //状态网格
    Vector moveAnimationStack;
    Vector scaleAnimationStack;
}
